# -*- coding: utf-8 -*-

import httplib2
import httplib

from urllib import quote as urlquote
from urllib import urlencode
import json
from urlparse import parse_qsl
import simplejson

REDU = "redu"

class OAuthException(Exception):
    pass


def get_oauth_client(service, key, secret, callback_url):
    """Get OAuth Client.
    
    Factory para criar o consumer OAuth apropriado
    """
    
    if service == REDU:
        return ReduConsumer(key, secret, callback_url)
    else:
        exception = "Servi�o OAuth desconhecido: %s" % service
        raise Exception, exception.encode('utf-8')


    
def parse_utf8_qsl(s):
    d = dict(parse_qsl(s))

    for k, v in d.items():
        if isinstance(k, unicode) and isinstance(v, unicode):
            continue
        d.pop(k)
        if not isinstance(k, unicode):
            k = unicode(k, 'utf-8')
        if not isinstance(v, unicode):
            v = unicode(v, 'utf-8')
        d[k] = v
    return d
    
class OAuthClient():

    def __init__(self, service_name, consumer_key, consumer_secret, request_url,
                 access_url, callback_url=None):
        """ Construtor """
        
        self.service_name = service_name
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.request_url = request_url
        self.access_url = access_url
        self.callback_url = callback_url

    def get_authorization_url(self):
        """ Get Authorization Url
        
        Retorna a url para autoriza��o da aplicação espec�fica do consumer em quest�o
        """
        raise NotImplementedError, "Deve ser implementado por uma subclasse"
    
    def get_access_token(self):
        raise NotImplementedError, "Deve ser implementado por uma subclasse"

class ReduConsumer(OAuthClient):
    """Redu Consumer.
    
    Um Consumer para conversar com a API do Redu utilizando OAuth como modelo de autentica��o.
    """

    def __init__(self, consumer_key, consumer_secret, callback_url):
        """Construtor."""
        
        OAuthClient.__init__(self,
            REDU,
            consumer_key,
            consumer_secret,
            "http://www.redu.com.br/oauth/request_token",
            "http://www.redu.com.br/oauth/token",
            callback_url)

    def get_authorization_url(self, response_type='code'):        
        return ("http://www.redu.com.br/oauth/authorize"
                "?redirect_uri=%s"
                "&response_type=%s"
                "&client_id=%s" % (urlquote(self.callback_url), response_type, self.consumer_key))
        
    def get_access_token(self, method='POST', data=None):

        grant_type = data.get('grant_type', 'authorization_code')

        if grant_type == 'client_credentials':
            data['auth'] = (self.consumer_key, self.consumer_secret)
        else:
            data.update(client_id=self.consumer_key,
                               client_secret=self.consumer_secret,
                               grant_type=grant_type)
        
        h = httplib2.Http()
        
        data['uri'] = self.access_url
        encodedData = urlencode(data)
        
        resp, content = h.request(self.access_url, method='POST', body=encodedData)

        return Response(content)
    
    def list_json(self, resource, oauth_token):
        url = 'http://redu.com.br/api/'
        url = url + resource + '.json?oauth_token=' + oauth_token
        headers={'content-type':'application/json'}
        
        h = httplib2.Http()  
        resp, content = h.request(url, 'GET', headers=headers)
        
        result = simplejson.loads(content)
        return result
    
    def post_wall(self, user_id, text, oauth_token):
        url = 'http://redu.com.br/api/users/' + str(user_id)
        url = url + '/statuses?oauth_token=' + oauth_token
        
        try:
            h = httplib2.Http()
            kw = dict(
                method='POST',
                headers={'Content-Type': 'application/json'},
                body=simplejson.dumps({'status': {'text': text}})
                )
            resp, content = h.request(url, **kw)
            status = 'rock and roll'
        except httplib.HTTPException, e:
            status= e
        
        return status
    
class Response(object):
    '''Response

    Container para tratar o conteúdo recebido
    '''
    def __init__(self, response):
        self.response = response

    @property
    def content(self):
        if isinstance(self.response, basestring):
            try:
                content = json.loads(self.response)
            except ValueError:
                content = parse_utf8_qsl(self, self.response)
        else:
            content = self.response
        return content